package cn.edu.xmu.orderpayment.order.dao;

import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.orderpayment.order.mapper.OrderItemPoMapper;
import cn.edu.xmu.orderpayment.order.mapper.OrderPoMapper;
import cn.edu.xmu.orderpayment.order.model.bo.Order;
import cn.edu.xmu.orderpayment.order.model.bo.OrderItem;
import cn.edu.xmu.orderpayment.order.model.po.OrderItemPo;
import cn.edu.xmu.orderpayment.order.model.po.OrderItemPoExample;
import cn.edu.xmu.orderpayment.order.model.po.OrderPo;
import cn.edu.xmu.orderpayment.order.model.po.OrderPoExample;
import cn.edu.xmu.orderpayment.order.model.vo.SimpleOrderInfoRetVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.lettuce.core.StrAlgoArgs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;
import static cn.edu.xmu.privilegegateway.annotation.util.Common.setPoModifiedFields;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;

/**
 * @author Chencheng Liao 22920192204238
 * @date 2021/12/11
 */

@Repository
public class OrderDao {
    private Logger logger = LoggerFactory.getLogger(OrderDao.class);
    @Autowired
    OrderPoMapper orderPoMapper;

    @Autowired
    OrderItemPoMapper orderItemPoMapper;


    /**
     * 获得订单所有状态
     *
     * @param
     * @return Object
     * @author Chencheng Liao 22920192204238
     * @Date 2021/12/11
     */
    public ReturnObject getOrderState() {
        List<Map<String, Object>> stateList = new ArrayList<>();
        for (Order.State state : Order.State.values()) {
            Map<String, Object> temp = new HashMap<>();
            temp.put("code", state.getCode());
            temp.put("name", state.getDescription());
            stateList.add(temp);
        }
        return new ReturnObject<>(stateList);
    }

    public ReturnObject<Order> getOrderById(Long id) {
        OrderPo orderPo;
        try {
            orderPo = orderPoMapper.selectByPrimaryKey(id);
        }
        catch (Exception e) {
            return new ReturnObject<>(ReturnNo.INTERNAL_SERVER_ERR);
        }

        Order order = (Order) cloneVo(orderPo, Order.class);
        return new ReturnObject<>(order);
    }

    /**
    * @Description: 修改订单
    * @Author: Li Yixuan 22920192204232
    * @Modified: 2021/12/13
    */
    public ReturnObject updateOrder(Order order,Long userId, String userName) {
        try{
            OrderPo orderPo = cloneVo(order,OrderPo.class);
            setPoModifiedFields(orderPo, userId, userName);
            orderPoMapper.updateByPrimaryKeySelective(orderPo);
            return new ReturnObject(orderPoMapper.selectByPrimaryKey(orderPo.getId()));
        }catch (Exception e){
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }


    public ReturnObject updateOrderState(Order order) {
        int ret;
        try {
            OrderPo orderPo = (OrderPo) cloneVo(order, OrderPo.class);
            ret = orderPoMapper.updateByPrimaryKeySelective(orderPo);
        }
        catch (Exception e) {
            return new ReturnObject<>(ReturnNo.INTERNAL_SERVER_ERR);
        }
        if (ret == 0) {
            return new ReturnObject(ReturnNo.FIELD_NOTVALID);
        }
        else return new ReturnObject();
    }

    /**
     * 买家查看查询名下的订单(概要)
     * @return object
     * @author Chencheng Liao 22920192204238
     * @Date 2021/12/13
     */
    public ReturnObject customerGetAllSimpleOrders(Long loginUser, String orderSn, Integer state, ZonedDateTime beginTime, ZonedDateTime endTime, Integer page, Integer pageSize) {
        try {
            OrderPoExample example = new OrderPoExample();
            OrderPoExample.Criteria criteria = example.createCriteria();
            criteria.andCustomerIdEqualTo(loginUser);
            criteria.andBeDeletedEqualTo(Byte.valueOf("0"));
            if (orderSn != null) {
                criteria.andOrderSnEqualTo(orderSn);
            }
            if (state != null) {
                if(state==200){
                    criteria.andStateGreaterThanOrEqualTo(200);
                    criteria.andStateLessThan(300);
                }
                else {
                    criteria.andStateEqualTo(state);
                }
            }
            if (beginTime != null) {
                criteria.andGmtCreateGreaterThanOrEqualTo(beginTime.withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime());
            }
            if (endTime != null) {
                criteria.andGmtCreateLessThanOrEqualTo(endTime.withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime());
            }
            PageHelper.startPage(page,pageSize);
            List<OrderPo> list = orderPoMapper.selectByExample(example);
            list.sort( (order1, order2) -> order2.getGmtCreate().compareTo(order1.getGmtCreate()) );
            PageInfo<OrderPo> pageInfo = new PageInfo<>(list);
            ReturnObject returnObject = new ReturnObject(pageInfo);
            return returnObject;

        } catch (Exception e) {
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

    /**
     * 买家查询单个订单
     *
     * @param orderId 订单id
     * @return object
     * @author Chencheng Liao 22920192204238
     * @Date 2021/12/13
     */
    public ReturnObject getOrder(Long orderId) {
        try{
            OrderPo orderPo = orderPoMapper.selectByPrimaryKey(orderId);
            if(orderPo==null){
                return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST,"该订单不存在");
            }
            Order order = cloneVo(orderPo,Order.class);//根据PO创建BO对象
            return new ReturnObject(order);
        }
        catch (Exception e){
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

    /**
    * @Description: 买家逻辑删除本人名下订单
    * @Param:
    * @return:
    * @Author: Li Yixuan 22920192204232
    * @Date: 2021/12/15
    */
    public ReturnObject cutomerDeleteOrder(Long id) {
        int ret;
        try {
            OrderPo orderPo = orderPoMapper.selectByPrimaryKey(id);
            orderPo.setBeDeleted((byte)1);
            orderPoMapper.updateByPrimaryKeySelective(orderPo);
        }
        catch (Exception e) {
            return new ReturnObject<>(ReturnNo.INTERNAL_SERVER_ERR);
        }
        return new ReturnObject();
    }

    /**
     * 店家查询订单概要
     *
     * @param shopId 商户id
     * @param customerId 查询的购买者用户id
     * @param orderSn 订单编号
     * @param beginTime 时间下限
     * @param endTime 时间上限
     * @param page 分页
     * @param pageSize 分页大小
     * @return object
     * @author Chencheng Liao 22920192204238
     * @Date 2021/12/16
     */
    public ReturnObject shopsShopIdOrdersGet(Long shopId, Long customerId, String orderSn, ZonedDateTime beginTime, ZonedDateTime endTime, Integer page, Integer pageSize) {
        try {
            OrderPoExample example = new OrderPoExample();
            OrderPoExample.Criteria criteria = example.createCriteria();
            if (shopId != 0) {
                criteria.andShopIdEqualTo(shopId);
            }
            if (orderSn != null) {
                criteria.andOrderSnEqualTo(orderSn);
            }
            if (customerId != null) {
                criteria.andCustomerIdEqualTo(customerId);
            }
            if (beginTime != null) {
                criteria.andGmtCreateGreaterThanOrEqualTo(beginTime.withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime());
            }
            if (endTime != null) {
                criteria.andGmtCreateLessThanOrEqualTo(endTime.withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime());
            }
            PageHelper.startPage(page,pageSize);
            List<OrderPo> list = orderPoMapper.selectByExample(example);
            list.sort( (order1, order2) -> order2.getGmtCreate().compareTo(order1.getGmtCreate()) );
            PageInfo<OrderPo> pageInfo = new PageInfo<>(list);
            ReturnObject returnObject = new ReturnObject(pageInfo);
            return cn.edu.xmu.oomall.core.util.Common.getPageRetVo(returnObject, SimpleOrderInfoRetVo.class);

        } catch (Exception e) {
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

    /**
     * 管理员取消订单
     * @param shopId
     * @param id 订单id
     * @return ReturnObject 返回对象
     * @author Chencheng Liao 22920192204238
     * @Date 2021/12/16
     */
    public ReturnObject shopsShopIdOrdersIdDelete(Long shopId, Long id) {
        OrderPo orderPo=orderPoMapper.selectByPrimaryKey(id);
        if(orderPo==null)
        {
            return new ReturnObject<>(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        //如果不是本店铺的订单则不能取消
        if(orderPo.getShopId()==null||(!orderPo.getShopId().equals(shopId)))
        {
            return new ReturnObject<>(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        //可取消状态
        if(orderPo.getState().intValue()<=Order.State.PENDING_DELIVERY.getCode())
        {
            orderPo.setState(Order.State.CANCELED.getCode().intValue());
        }
        else
        {
            return new ReturnObject<>(ReturnNo.STATENOTALLOW);
        }
        int ret;
        try{
            ret=orderPoMapper.updateByPrimaryKeySelective(orderPo);
        }
        catch (Exception e) {
            return new ReturnObject<>(ReturnNo.INTERNAL_SERVER_ERR,e.getMessage());
        }
        //检查更新是否成功
        if(ret==0)
        {
            return new ReturnObject<>(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        return new ReturnObject<>();
    }

    /**
    * @Description: 通过pid和用户信息获取suborder
    * @Author: Li Yixuan 22920192204232
    * @Date: 2021/12/24
    */
    public ReturnObject getSubOrdersByPid(Long pid,Long loginUser,List<Integer> stateList)
    {
        //通过example进行查询
        OrderPoExample example=new OrderPoExample();
        OrderPoExample.Criteria criteria=example.createCriteria();
        criteria.andBeDeletedNotEqualTo((byte)1);//暂时以1表示被删除，表示0存在
        criteria.andStateIn(stateList);
        example.setOrderByClause("gmt_create DESC");
        if (loginUser != null) {
            criteria.andCustomerIdEqualTo(loginUser);
        }
        if (pid != null) {
            criteria.andPidEqualTo(pid);
        }
        try{
            List<OrderPo> orderPos=new ArrayList<>();
            List<Order> orders=new ArrayList<>();
            orderPos=orderPoMapper.selectByExample(example);
            for(OrderPo op:orderPos)
            {
                Order order = (Order) cloneVo(op, Order.class);
                orders.add(order);
            }
            return new ReturnObject(orders);
        }catch (DataAccessException e){
            return new ReturnObject<>(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
    }

//    public ReturnObject getOrderByGrouponActivityId(Long grouponActivityId){
//        try {
//            OrderPoExample example=new OrderPoExample();
//            OrderPoExample.Criteria criteria=example.createCriteria();
//            criteria.andGrouponIdEqualTo(grouponActivityId);
//            List<OrderPo> orderPos = orderPoMapper.selectByExample(example);
//            if(orderPos.size()==0){
//                return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST,"没有此团购活动");
//            }
//            return new ReturnObject(orderPos);
//        }
//        catch (Exception exception){
//            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR,exception.getMessage());
//        }
//    }


    public ReturnObject createOrder(Order order) {
        try{
            OrderPo po=cloneVo(order,OrderPo.class);
            orderPoMapper.insertSelective(po);
            return new ReturnObject(po);
        }
        catch (Exception e){
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

    public ReturnObject createOrderItem(OrderItem orderItem){
        try{
            OrderItemPo po=cloneVo(orderItem,OrderItemPo.class);
            orderItemPoMapper.insertSelective(po);
            return new ReturnObject(po);
        }
        catch (Exception e){
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

    public ReturnObject<OrderItem> getOrderItemById(Long id) {
        try{
            OrderItemPo po=orderItemPoMapper.selectByPrimaryKey(id);
            if(po==null)return new ReturnObject<>(ReturnNo.RESOURCE_ID_NOTEXIST,"该订单明细不存在");
            return new ReturnObject<>(cloneVo(po,OrderItem.class));
        }catch (Exception e){
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }


    public  ReturnObject getOrderByOrderSn(String orderSn){
        try{
            OrderPoExample oe=new OrderPoExample();
            OrderPoExample.Criteria cr=oe.createCriteria();
            cr.andOrderSnEqualTo(orderSn);
            List<OrderPo> pos=orderPoMapper.selectByExample(oe);
            if(pos==null||pos.size()==0)return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
            return new ReturnObject<>(pos.get(0));
        }
        catch (Exception e){
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

    public ReturnObject<List> getOrderItemsByOrderId(Long orderId) {
        try{
            OrderItemPoExample example=new OrderItemPoExample();
            OrderItemPoExample.Criteria criteria=example.createCriteria();
            criteria.andOrderIdEqualTo(orderId);
            List<OrderItemPo> list = orderItemPoMapper.selectByExample(example);
            return new ReturnObject(list);
        }catch (Exception e){
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

    public ReturnObject updateOrderItem(OrderItemPo orderItemPo){
        try{
            orderItemPoMapper.updateByPrimaryKeySelective(orderItemPo);
            return new ReturnObject<>();
        }
        catch (Exception e){
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }

    public  ReturnObject getOrderByPid(Long pid){
        try{
            OrderPoExample oe=new OrderPoExample();
            OrderPoExample.Criteria cr=oe.createCriteria();
            cr.andPidEqualTo(pid);
            List<OrderPo> pos=orderPoMapper.selectByExample(oe);
            if(pos==null||pos.size()==0)return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
            return new ReturnObject<>(pos);
        }
        catch (Exception e){
            logger.error(e.getMessage());
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
    }
}
